home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / binmail / mhlock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-12  |  3.9 KB  |  230 lines

  1. /* lock.c - universal locking routines */
  2. #ifndef    lint
  3. static char ident[] = "@(#)$Id: mhlock.c,v 1.1 90/11/23 13:52:46 asjl Exp Locker: asjl $";
  4. #endif    lint
  5.  
  6. #if defined(MH_LCK_BEL)
  7.  
  8. #include <stdio.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11.  
  12. #define    NOTOK    (-1)
  13. #define    OK    0
  14.  
  15. #define    NULLCP    ((char *) 0)
  16.  
  17. #ifdef    SYS5
  18. #define    index    strchr
  19. #define    rindex    strrchr
  20. #endif    SYS5
  21.  
  22. extern int  errno;
  23.  
  24. static int    lockit();
  25. static        lockname(), timerON(), timerOFF();
  26.  
  27. long    time ();
  28.  
  29. int  lkopen (file, access)
  30. register char   *file;
  31. register int     access;
  32. {
  33.     register int    i,
  34.                     j;
  35.     long    curtime;
  36.     char    curlock[BUFSIZ],
  37.             tmplock[BUFSIZ];
  38.     struct stat st;
  39.  
  40.     if (stat (file, &st) == NOTOK)
  41.     return NOTOK;
  42.     lockname (curlock, tmplock, file);
  43.     
  44.     for (i = 0;;)
  45.     switch (lockit (tmplock, curlock)) {
  46.         case OK: 
  47.         if ((i = open (file, access)) == NOTOK) {
  48.             j = errno;
  49.             (void) unlink (curlock);
  50.             errno = j;
  51.         }
  52.         timerON (curlock, i);
  53.         return i;
  54.  
  55.         case NOTOK: 
  56.         if (stat (curlock, &st) == NOTOK) {
  57.             if (i++ > 5)
  58.             return NOTOK;
  59.             sleep (5);
  60.             break;
  61.         }
  62.  
  63.         i = 0;
  64.         (void) time (&curtime);
  65.         if (curtime < st.st_ctime + 60L)
  66.             sleep (5);
  67.         else
  68.             (void) unlink (curlock);
  69.         break;
  70.     }
  71. }
  72.  
  73.  
  74. static int  lockit (tmp, file)
  75. register char   *tmp,
  76.             *file;
  77. {
  78.     register int    fd;
  79.  
  80.     if ((fd = creat (tmp, 0400)) == NOTOK)
  81.     return NOTOK;
  82. #ifdef hpux
  83.     write(fd, "binmail lock\n",8);
  84. #endif hpux
  85.     (void) close (fd);
  86.  
  87.     fd = link (tmp, file);
  88.     (void) unlink (tmp);
  89.  
  90.     return (fd != NOTOK ? OK : NOTOK);
  91. }
  92.  
  93. /*   */
  94.  
  95. static  lockname (curlock, tmplock, file)
  96. register char   *curlock,
  97.             *tmplock,
  98.             *file;
  99. {
  100.     register char  *cp;
  101.     extern char *rindex();
  102.  
  103.     (void) sprintf (curlock, "%s.lock", file);
  104.     
  105.     if (tmplock)
  106.     {
  107.     if ((cp = rindex (curlock, '/')) == NULL || *++cp == NULL)
  108.             (void) strcpy (tmplock, ",LCK.XXXXXX");
  109.         else
  110.             (void) sprintf (tmplock, "%.*s,LCK.XXXXXX",
  111.                 cp - curlock, curlock);
  112.     (void) unlink (mktemp (tmplock));
  113.     }
  114. }
  115.  
  116. /*   */
  117.  
  118. int     lkclose (fd, file)
  119. register int     fd;
  120. register char   *file;
  121. {
  122.     char    curlock[BUFSIZ];
  123.     struct stat st;
  124.  
  125.     if (fd == NOTOK)
  126.     return OK;
  127.     if (fstat (fd, &st) != NOTOK)
  128.     {
  129.     lockname (curlock, NULLCP, file);
  130.     (void) unlink (curlock);
  131.     timerOFF (fd);
  132.     }
  133.  
  134.     return (close (fd));
  135. }
  136.  
  137. /*   */
  138.  
  139. #include <signal.h>
  140.  
  141. #define    NSECS    ((unsigned) 20)
  142.  
  143.  
  144. struct lock {
  145.     int         l_fd;
  146.     char    *l_lock;
  147.     struct lock *l_next;
  148. };
  149. #define    NULLP    ((struct lock *) 0)
  150.  
  151. static struct lock *l_top = NULLP;
  152.  
  153.  
  154. /* ARGSUSED */
  155.  
  156. static alrmser (sig)
  157. int    sig;
  158. {
  159.     register int    j;
  160.     register char  *cp;
  161.     register struct lock   *lp;
  162.  
  163. #ifndef    BSD42
  164.     (void) signal (SIGALRM, alrmser);
  165. #endif    BSD42
  166.  
  167.     for (lp = l_top; lp; lp = lp -> l_next)
  168.     if (*(cp = lp -> l_lock) && (j = creat (cp, 0400)) != NOTOK)
  169.         (void) close (j);
  170.  
  171.     (void) alarm (NSECS);
  172. }
  173.  
  174. /*   */
  175.  
  176. static timerON (lock, fd)
  177. char   *lock;
  178. int    fd;
  179. {
  180.     register struct lock   *lp;
  181.  
  182.     if ((lp = (struct lock *) malloc ((unsigned) (sizeof *lp))) == NULLP)
  183.     return;            /* XXX */
  184.  
  185.     lp -> l_fd = fd;
  186.     if ((lp -> l_lock = malloc ((unsigned) (strlen (lock) + 1))) == NULLCP) {
  187.     free ((char *) lp);
  188.     return;            /* XXX */
  189.     }
  190.     (void) strcpy (lp -> l_lock, lock);
  191.     lp -> l_next = NULLP;
  192.  
  193.     if (l_top)
  194.     lp -> l_next = l_top -> l_next;
  195.     else {
  196.     (void) signal (SIGALRM, alrmser);/* perhaps SIGT{STP,TIN,TOU} */
  197.     (void) alarm (NSECS);
  198.     }
  199.     l_top = lp;
  200. }
  201.  
  202.  
  203. static timerOFF (fd)
  204. int    fd;
  205. {
  206.     register struct lock   *pp,
  207.                            *lp;
  208.  
  209.     (void) alarm (0);
  210.  
  211.     if (l_top) {
  212.     for (pp = lp = l_top; lp; pp = lp, lp = lp -> l_next)
  213.         if (lp -> l_fd == fd)
  214.         break;
  215.     if (lp) {
  216.         if (lp == l_top)
  217.         l_top = lp -> l_next;
  218.         else
  219.         pp -> l_next = lp -> l_next;
  220.  
  221.         free (lp -> l_lock);
  222.         free ((char *) lp);
  223.     }
  224.     }
  225.  
  226.     if (l_top)
  227.     (void) alarm (NSECS);
  228. }
  229. #endif /* MH_LCK_BEL */
  230.